/*
 * Copyright 2007-2010 VTT Biotechnology
 * This file is part of DP.
 *
 * DP is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * DP is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * DP; if not, write to the Free Software Foundation, Inc., 51 Franklin St,
 * Fifth Floor, Boston, MA 02110-1301 USA
 */
package PD.data.impl.datasets;

import PD.data.Row;
import PD.data.NetworkDataset;
import java.util.ArrayList;
import java.util.List;

/**
 * Basic data set implementation.
 *
 * @author SCSANDRA
 */
public class SimpleNetworkDataset implements NetworkDataset {

        String datasetName;
        List<Row> Nodes;
        List<Row> Edges;

        /**
         *
         * @param datasetName Name of the data set
         */
        public SimpleNetworkDataset(String datasetName) {
                this.datasetName = datasetName;
                this.Edges = new ArrayList<Row>();
                this.Nodes = new ArrayList<Row>();
        }

        public String getDatasetName() {
                return this.datasetName;
        }

        public void setDatasetName(String datasetName) {
                this.datasetName = datasetName;
        }

        @Override
        public SimpleNetworkDataset clone() {
                SimpleNetworkDataset newDataset = new SimpleNetworkDataset(this.datasetName);
                newDataset.Edges = new ArrayList<Row>();
                newDataset.Nodes = new ArrayList<Row>();

                for (Row edge : this.Edges) {
                        newDataset.Edges.add(edge.clone());
                }

                for (Row node : this.Nodes) {
                        newDataset.Nodes.add(node.clone());
                }
                return newDataset;
        }

        public int getNumberEdgesRows() {
                return this.Edges.size();
        }

        public int getNumberNodesRows() {
                return this.Nodes.size();
        }

        public Row getEdgesRow(int indexRow) {
                return this.Edges.get(indexRow);
        }

        public void removeEdgesRow(Row row) {
                this.Edges.remove(row);
        }

        public void removeNodesbyID(int id) {
                List<Row> removeList = new ArrayList<Row>();
                for (Row row : this.Nodes) {
                        if (row.getID() == id) {
                                removeList.add(row);

                        }
                }
                for (Row row : removeList) {
                        this.Nodes.remove(row);
                }
        }

        public Row getNodesRow(int indexRow) {
                return this.Nodes.get(indexRow);
        }

        public Row getNodesRowByID(int indexRow) {
                for (Row row : this.Nodes) {
                        if (row.getID() == indexRow) {
                                return row;
                        }
                }
                return null;
        }

        public Row getEdgesRowByID(int indexRow) {
                for (Row row : this.Edges) {
                        if (row.getID() == indexRow) {
                                return row;
                        }
                }
                return null;
        }

        public List<Row> getEdgesfromSourceID(int indexRow) {
                List<Row> edges = new ArrayList<Row>();
                for (Row row : this.Edges) {
                        if (row.getSourceVertexID() == indexRow) {
                                edges.add(row);
                        }
                }
                return edges;
        }

        public void removeNodesRow(Row row) {
                this.Nodes.remove(row);
        }

        public List<Row> getNodesRows() {
                return this.Nodes;
        }

        public List<Row> getEdgesRows() {
                return this.Edges;
        }

        public void setNodesRow(Row row) {
                this.Nodes.add(row);
        }

        public void setEdgesRow(Row row) {
                this.Edges.add(row);
        }

        public void setNodesRows(List<Row> Nodes) {
                this.Nodes = Nodes;
        }

        public void setEdgesRows(List<Row> Edges) {
                this.Edges = Edges;
        }

        public List<Row> getConnectedNodes(int ID) {
                List<Row> connectedNodes = new ArrayList<Row>();
                for (Row edge : this.Edges) {
                        if (edge.getSourceVertexID() == ID) {
                                int newNodeID = edge.getTargetVertexID();
                                Row node = this.getNodesRowByID(newNodeID);
                                if (!connectedNodes.contains(edge) && !connectedNodes.contains(node)) {
                                        connectedNodes.add(edge);
                                        connectedNodes.add(node);
                                }
                        } else if (edge.getTargetVertexID() == ID) {
                                int newNodeID = edge.getSourceVertexID();
                                Row node = this.getNodesRowByID(newNodeID);
                                if (!connectedNodes.contains(edge) && !connectedNodes.contains(node)) {
                                        connectedNodes.add(edge);
                                        connectedNodes.add(node);
                                }
                        }
                }
                return connectedNodes;
        }

        public boolean contains(int iD) {
                for (Row node : this.Nodes) {
                        if (node.getID() == iD) {
                                return true;
                        }
                }
                return false;
        }

        public void RemoveDesconnectedNodesAndEdges() {
                // Remove lonely Nodes
                List<Row> nodesToRemove = new ArrayList<Row>();
                for (Row node : this.Nodes) {
                        if (getConnectedNodes(node.getID()).isEmpty()) {
                                nodesToRemove.add(node);
                        }
                }

                for (Row node : nodesToRemove) {
                        this.Nodes.remove(node);
                }

                // Remove Edges
                List<Row> edgesToRemove = new ArrayList<Row>();
                for (Row edge : this.Edges) {
                        int source = edge.getSourceVertexID();
                        Row node = this.getNodesRowByID(source);
                        if (node == null) {
                                edgesToRemove.add(edge);
                        } else {
                                int target = edge.getTargetVertexID();
                                node = this.getNodesRowByID(target);
                                if (node == null) {
                                        edgesToRemove.add(edge);

                                }
                        }
                }

                for (Row edge : edgesToRemove) {
                        this.Edges.remove(edge);
                }

        }
}
